<template>
  <div class="intelligent-assistant">
    <a-card class="intelligent-assistant-card">
      <div class="message-box" id="scrollableContainer">
        <div
          class="item"
          v-for="item in dialogueList"
          :key="item.key"
          :class="item.title"
        >
          <div v-if="item.title === 'ai'" class="avatar">
            <SmileOutlined />
          </div>
          <div v-else class="avatar">A</div>
          <div class="message">{{ item.message }}</div>
        </div>
      </div>
      <div class="input-box">
        <a-textarea
          class="input"
          placeholder="请输入"
          :auto-size="{ maxRows: 5 }"
          v-model:value="inputValue"
        ></a-textarea>
        <a-button type="primary" :loading="loadingSend" @click="clickSend">
          发送
        </a-button>
        <a-dropdown placement="top">
          <a-button> 更多 </a-button>
          <template #overlay>
            <a-menu>
              <a-menu-item @click="clickClearChatRecords">
                <a href="javascript:;">清空聊天记录</a>
              </a-menu-item>
            </a-menu>
          </template>
        </a-dropdown>
      </div>
    </a-card>
  </div>
</template>
<script setup lang="ts">
  // 引入组件
  import { SmileOutlined } from '@ant-design/icons-vue'
  import api from '@/axios/api.js'
  // 引入方法
  import {
    defineProps,
    defineEmits,
    watch,
    onMounted,
    ref,
    nextTick,
  } from 'vue'
  import { message } from 'ant-design-vue'
  // import dayjs from 'dayjs'
  const props = defineProps({
    open: {
      default: false,
    },
  })
  const emits = defineEmits(['cancel'])
  const inputValue = ref('') //输入框值
  const formData = ref({
    model: 'deepseekr1',
    messages: [
      {
        role: 'system',
        content: '你是一个智能助手',
      },
    ],
    stream: true,
  })
  const dialogueList = ref([
    {
      title: 'ai',
      key: 0,
      message: '我是一个ai助手',
    },
  ]) //对话列表
  const loadingSend = ref(false)
  // 自定义状态
  onMounted(() => {
    const arr = localStorage.getItem('dialogueList')
    if (!arr) {
      localStorage.setItem('dialogueList', JSON.stringify(dialogueList.value))
    } else {
      dialogueList.value = JSON.parse(arr)
    }
    controlTheScrollBar()
  })
  //控制滚动条
  const controlTheScrollBar = () => {
    nextTick(() => {
      var container = document.getElementById('scrollableContainer')
      if (container) {
        container.scrollTop = container.scrollHeight
      }
    })
  }
  //点击发送
  const clickSend = () => {
    if (!inputValue.value) {
      message.error('不能发送空信息')
    } else {
      loadingSend.value = true
      dialogueList.value.push({
        title: 'user',
        key: Date.now() + 1,
        message: inputValue.value,
      })
      controlTheScrollBar()
      formData.value.messages.push({
        role: 'user',
        content: inputValue.value,
      })
      inputValue.value = undefined
      // 调用示例
      setTimeout(() => {
        fetchSSEPost(api.getDeepseekInfo, formData.value)
      }, 0)
    }
  }
  //获取ai消息
  const fetchSSEPost = async (url, body) => {
    let key = Date.now()
    let message = ''
    dialogueList.value.push({
      title: 'ai',
      key,
      message,
    })
    controlTheScrollBar()
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(body),
    })

    if (
      !response.ok ||
      response.headers.get('Content-Type') !== 'text/event-stream'
    ) {
      loadingSend.value = false
      throw new Error('Invalid SSE response')
    }

    const reader = response.body.getReader()
    const decoder = new TextDecoder('utf-8')
    let buffer = ''

    async function readChunk() {
      const { done, value } = await reader.read()
      if (done) return

      buffer += decoder.decode(value, { stream: true })
      const lines = buffer.split('\n\n')
      buffer = lines.pop() // 保留未处理完的数据

      for (const line of lines) {
        if (line.startsWith('data:')) {
          const data = line.replace(/^data:\s*/, '')
          controlTheScrollBar()
          if (data === '[DONE]') {
            localStorage.setItem(
              'dialogueList',
              JSON.stringify(dialogueList.value)
            )
            loadingSend.value = false
            return
          }
          try {
            const parsedData = JSON.parse(data)
            dialogueList.value.forEach(item => {
              if (item.key === key) {
                item.message += parsedData.choices[0].delta.content
                  .replace('<think>', '')
                  .replace('</think>', '')
              }
            })
          } catch (e) {
            console.error('Parse error:', data)
            loadingSend.value = false
          }
        }
      }
      readChunk() // 递归读取下一块
    }
    readChunk()
  }
  //点击清空聊天记录
  const clickClearChatRecords = () => {
    dialogueList.value = [
      {
        title: 'ai',
        key: 0,
        message: '我是一个ai助手',
      },
    ]
    formData.value = {
      model: 'deepseekr1',
      messages: [
        {
          role: 'system',
          content: '你是一个智能助手',
        },
      ],
      stream: true,
    }
    localStorage.removeItem('dialogueList')
    localStorage.setItem('dialogueList', JSON.stringify(dialogueList.value))
  }
</script>
<style lang="less" scoped>
  .intelligent-assistant {
    height: 100%;
    .intelligent-assistant-card {
      height: 100%;
      .message-box {
        padding: (24 / @vw);
        height: (810 / @vh);
        overflow: auto;
        &::-webkit-scrollbar {
          display: none;
        }
        .item {
          display: flex;
          margin-bottom: (20 / @vh);
          .avatar {
            margin-top: (6 / @vw);
            margin-right: (10 / @vw);
            width: (36 / @vw);
            height: (36 / @vw);
            border-radius: (36 / @vw);
            background-color: @tc;
            color: #fff;
            font-size: (18 / @vw);
            text-align: center;
            line-height: (36 / @vw);
          }
          .message {
            padding: (16 / @vw);
            max-width: 80%;
            background-color: rgba(229, 0, 39, 0.3);
            border-radius: (10 / @vw);
            box-shadow: 2px 2px 6px 0px rgba(0, 0, 0, 0.1);
          }
        }
        .user {
          flex-direction: row-reverse;
          .avatar {
            margin-right: 0;
          }
          .message {
            margin-right: (10 / @vw);
            background-color: #fff;
          }
        }
      }
      .input-box {
        display: flex;
        height: 100%;
        gap: (10 / @vw);
      }
    }
  }
</style>
